home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / math / gle-3.000 / gle-3 / gle / polish.c < prev    next >
C/C++ Source or Header  |  1995-02-07  |  11KB  |  434 lines

  1. char *un_quote();
  2. char *ns[3] = {"Nothing","Number","String"};
  3. extern int gle_debug;
  4. /*---------------------------------------------------------------------------*/
  5. #include "all.h"
  6.  
  7. #include <math.h>
  8. int add_strvar(char *pcode,int *plen,int i);
  9. int token_norm(void);
  10. int token_space(void);
  11.  
  12. #define true (!false)
  13. #define false 0
  14. #define tok(n)  tk[n]
  15. #define abort goto fatal_err
  16. /*---------------------------------------------------------------------------*/
  17. /* bin = 10..29, binstr = 30..49, fn= 60...139, userfn=200..nnn */
  18. #define stack_bin(i,p)     stack_op(pcode,plen,stk,stkp,&nstk,i-10+(last_typ*20),p+curpri)
  19. #define stack_fn(i)     stack_op(pcode,plen,stk,stkp,&nstk,i+60,10+curpri)
  20. #define dbg if ((gle_debug & 4)>0)
  21. /*---------------------------------------------------------------------------*/
  22. /* Input is token array, and pointer to current point, output is pcode */
  23.  
  24. /* typedef struct op_key (*OPKEY)[100];  */
  25. /* typedef char (*(*TOKENS)[500]); */
  26.  
  27. void long_set(char *pcode,int32 i);
  28. int zpolish(TOKENS tk,int *ntok,int *curtok,char *pcode,int *plen,int *rtype);
  29. polish(char *expr,char *pcode,int *plen,int *rtype)
  30. {
  31. static char inbuff[200];
  32. static char *tk[500];
  33. static char tkbuff[500];
  34. static int ntk,ct;
  35. char *space_str=" ";
  36.     static char buff[50];
  37.     static int start_token;
  38.     double xxx;
  39.     int idx,ret,np,*plist,saveplen,term_bracket;
  40.     int curpri=0;
  41.     int i,j,v,p,savelen,isa_string,not_string,last_typ;
  42.     int nstk=0,stk[50],stkp[50];    /* stack for operators */
  43.     int unary=1;        /* binary or unary operation expected */
  44.     int ln;            /* length of current token */
  45.     char *cts;        /* current token */
  46.     /* last_typ, 1=number,2=string */
  47.  
  48.     if (tk[400]==NULL) for (i=0;i<500;i++) tk[i] = space_str;
  49.     isa_string = false;
  50.     not_string = false;
  51.     if (*rtype==1) not_string = true;
  52.     /* if (*rtype==2) isa_string = true; */
  53.     *plen = *plen*4;    /* change into byte count */
  54.     if (*rtype>0) term_bracket = true;
  55.     last_typ = *rtype;
  56.     saveplen = *plen;
  57.  
  58.     add_i(pcode,plen,1);    /* expression follows */
  59.     savelen = *plen;    /* Used to set acutal length at end */
  60.     add_i(pcode,plen,0);    /* Length of expression */
  61.     dbg gprint("====Start of expression {%s} \n",expr);
  62.     if (strlen(expr)==0) {gprint("Zero length expression\n"); return;}
  63.     if (!start_token) {
  64.         ntk = 0; ct=1;
  65.         token_norm();
  66.         token(expr,(TOKENS) tk,&ntk,tkbuff);
  67.         token_space();
  68.     }
  69.     for (;;) {
  70.       cts = tok(ct);
  71.       dbg gprint("First word token=%d via (1=unary %d) cts {%s} %d \n "
  72.         ,ct,unary,cts,strlen(cts));
  73.       ln = strlen(cts);
  74.        switch (unary) {
  75.       case 1:  /* a unary operator, or function, or number or variable */
  76.         if (ln==1 && (*cts=='-' || *cts=='E')) goto notnumber;
  77.         if (isnumber(cts))  {
  78. evalagain:            dbg gprint("Found number {%s}\n",cts);
  79.             if (lastchar(cts,'E'))  {
  80.                 strcpy(buff,cts);
  81.                 strcat(buff,tok(++ct));
  82.                 if (*tok(ct)=='-' || *tok(ct)=='+') {
  83.                     strcat(buff,tok(++ct));
  84.                 }
  85.                 tok(ct) = buff;
  86.                 cts = tok(ct);
  87.                 goto evalagain;
  88.             }
  89.             xxx = atof(cts);
  90.             add_f(pcode,plen,xxx);
  91.             if (last_typ==2) gprint("Expecting string {%s} \n",cts);
  92.             last_typ = 1;
  93.             unary=2; break;
  94.         }
  95. notnumber:    /* NOT a number, Is it a built in function */
  96.         /* int idx,ret,np,*plist; */
  97.         find_un(cts,&idx,&ret,&np,&plist);    /* 1,2 = +,- */
  98.         if (idx>3) {
  99.           dbg gprint("Found built in function \n");
  100.             if (*tok(++ct)!='(') {
  101.                 gprint("Expecting left bracket after function name");
  102.                 abort;
  103.             }
  104.             {
  105.              char fcode[400];
  106.              char *fp;
  107.              int flen,vtype,nparam=0;
  108.              if (*tok(ct+1)!=')') {
  109.                while (*tok(ct)!=')') {
  110.                 nparam++;
  111.                 vtype = *(plist+nparam-1);
  112.                 flen = 0;
  113.                 (ct)++;
  114.                 start_token = true;
  115.                 polish("xx",fcode,&flen,&vtype);
  116.                 start_token = false;
  117.                 flen = flen * 4;
  118.                 if (nparam>np) {gprint("Too many parameters got=%d want=%d \n",nparam,np);abort;}
  119.                 if (vtype==0) abort;
  120.                 add_pcode(pcode,plen,fcode,&flen);
  121.                }
  122.              } else {
  123.                 ct++;
  124.              }
  125.             }
  126.             if (last_typ==(3-ret)) {
  127.                 gprint("Function of wrong type Expecting {%s} \n",ns[ret]);
  128.                 abort;
  129.             }
  130.             last_typ = ret;
  131.             add_fn(pcode,plen,idx+60);
  132.             unary = 2; break;
  133.         } else if (idx>0) {
  134.             stack_fn(idx);
  135.             unary=1; break;
  136.         }
  137.  
  138.          /* Is it a user-defined function, identical code too above. */
  139.           sub_find(cts,&idx,&ret,&np,&plist);    /* 1,2 = +,- */
  140.           if (idx>0) {
  141.           dbg gprint("Found user function \n");
  142.             if (*tok(++ct)!='(') {
  143.                 gprint("Expecting left bracket after function name");
  144.                 abort;
  145.             }
  146.             {
  147.             char fcode[400];
  148.             char *fp;
  149.             int flen,nnn,vtype,nparam=0;
  150.             if (*tok(ct+1)!=')') {
  151.              while (*tok(ct)!=')') {
  152.                 ct++;
  153.                 nparam++;
  154.                 vtype = *(plist+nparam-1);
  155.                 nnn = *(plist+nparam);
  156.                 flen = 0;
  157.                 start_token = true;
  158.                 polish("xx",fcode,&flen,&vtype);
  159.                 start_token = false;
  160.                 flen = flen * 4;
  161.                 if (nparam>np) {gprint("Too many U paramters got=%d want=%d \n",nparam,np);abort;}
  162.                 if (vtype==0) abort;
  163.                 add_pcode(pcode,plen,fcode,&flen);
  164.               }
  165.              } else {
  166.                 ct++;
  167.              }
  168.             }
  169.             if (last_typ==(3-ret)) {
  170.                 gprint("Function of wrong type Expecting {%s} \n",ns[ret]);
  171.                 abort;
  172.             }
  173.             if (ret>0 && ret<3) last_typ = ret;
  174.             add_fn(pcode,plen,idx+200);
  175.             unary = 2; break;
  176.         } else if (idx>0) {
  177.             stack_fn(idx);
  178.             unary=1; break;
  179.         }
  180.  
  181.  
  182.         /* Is it a 'known' variable */
  183.         var_find(cts,&v,&ret);
  184.         if (v>=0) {
  185.             dbg gprint("Found variable %d \n",v);
  186.         /*    if (last_typ==(3-ret)) {
  187.                 gprint("Expecting {%s} \n",ns[last_typ]);
  188.                 abort;
  189.             }*/
  190.             last_typ=ret;
  191.             if (ret==2) add_strvar(pcode,plen,v);
  192.             else add_var(pcode,plen,v);
  193.             unary=2; break;
  194.         }
  195.         /* Is it a atring */
  196.         if (*cts=='"') {
  197.           dbg gprint("Found string \n");
  198.             /*if (last_typ==1) {
  199.                 gprint("Expecting number {%s} \n",cts);
  200.                 abort;
  201.             }*/
  202.             last_typ = 2;
  203.             add_string(pcode,plen,un_quote(cts));    /* remove quotes */
  204.             unary = 2; break;
  205.         }
  206.         if (*cts=='(') { curpri = curpri + 100; break; }
  207.         if (*cts==')') {
  208.             if (curpri>0) {
  209.                 curpri = curpri - 100;
  210.                 unary = 2; break;
  211.             }
  212.             gprint("Too many right brackets found in exp \n");
  213.  
  214.         }
  215.         /* must be unquoted string, unless a binary operator
  216.         was found, in which case it is an undelcared variable */
  217.         if (not_string) {
  218.             dbg gprint("Found un-initialized variable {%s} /n",cts);
  219.             var_add(cts,&v,&ret);
  220.             last_typ=ret;
  221.             add_var(pcode,plen,v) ;
  222.             unary=2;
  223.             break;
  224.         }
  225.         last_typ = 2;
  226.         dbg printf("Unquoted string (%s) \n",cts);
  227.         add_string(pcode,plen,un_quote(cts));    /* remove quotes */
  228.         isa_string = true;
  229.         unary = 2; break;
  230. #if 0
  231.         /* this code fragment is redundant ! */
  232.         isa_string = true;
  233.         add_string(pcode,plen,cts);
  234.         unary = 2;  /* Expecting end of expression next !! */
  235.         break;
  236. #endif
  237.       case 2:  /* a binary operator, or space, or end of line */
  238.         if (ct>ntk || *cts==' ' || *cts==',' ) {
  239.             goto end_expression;
  240.         }
  241.         if (*cts==')' && curpri==0) {
  242.             goto end_expression;
  243.         }
  244. /* MIGHT (gives error with a$ = b$+c$) */
  245.         if (isa_string) {
  246.             gprint("Expression contained unquoted string\n");
  247.             abort;
  248.         }
  249.  
  250.         not_string = true;
  251.         /* Binary operators, +,-,*,/,^,<,>,<=,>=,.and.,.or. */
  252.         switch (*cts) {
  253.           case '+' : v = 1; p=2; break;
  254.           case '-' : v = 2; p=2; break;
  255.           case '*' : v = 3; p=3; break;
  256.           case '/' : v = 4; p=3; break;
  257.           case '^' : v = 5; p=4; break;
  258.           case '=' : v = 6; p=1; break;
  259.           case '&' : v = 12; p=1; break;
  260.           case '|' : v = 13; p=1; break;
  261.           case '<' : v = 7; p=1;
  262.             if (*tok(ct+1)=='=') {v=8;++ct; break;}
  263.             if (*tok(ct+1)=='>') {v=11;++ct; break;}
  264.             break;
  265.           case '>' : v = 9;p=1;
  266.             if (*tok(ct+1)=='=') {v=10;++ct; break;}
  267.             break;
  268.           case '.' : p=1;
  269.             if (strcmp(cts,".AND.")==0) {v=12; break;}
  270.             if (strcmp(cts,".OR.")==0) {v=13; break;}
  271.             break;
  272.            default : v = 0 ; break;
  273.         }
  274.         if (v>0) {
  275.             if (last_typ<1 || last_typ > 3) last_typ = 1;
  276.             dbg gprint("stack, i %d, type %d \n",v,last_typ);
  277.             stack_bin(v,p);
  278.             dbg gprint("Found binary operator \n");
  279.             unary=1; break;
  280.         }
  281.         if (*cts==')') {
  282.             if (curpri>0) {
  283.                 curpri = curpri - 100;
  284.                 unary = 2; break;
  285.             }
  286.             if (term_bracket!=true) {
  287.                 gprint("Too many right brackets, expecting binary operator \n");
  288.                 abort;
  289.             }
  290.             goto end_expression;
  291.         }
  292.       }
  293.       if (++ct>ntk) { goto end_expression; }
  294. /*    gprint("Next token is {%s} \n",tok(ct)); */
  295.     }
  296. end_expression:
  297.     if (*tok(ct)==' ') (ct)++;
  298.     dbg gprint("Got expression , curtok=%d {%s} \n",ct,tok(ct));
  299.     *rtype = last_typ;
  300.       dbg gprint("Found END OF EXPRESSION \n");
  301.     if (!start_token) if (curpri!=0) {gprint("Missing right brackets");}
  302.     /* Pop everything off the stack */
  303.     for (i=nstk;i>0;i--) {
  304.         dbg gprint("Adding left over operators  I = %d  op=%d \n",i,stk[i]);
  305.         add_i(pcode,plen,stk[i]);
  306.     }
  307.     long_set(pcode+savelen,(int32) (*plen - savelen)/4-1);  /* Set length of expression */
  308.  
  309.     *plen = *plen/4;    /* change back to int count */
  310.     /*    printf("pcode ");
  311.           for (i=saveplen;i<4*(*plen);i++) printf("%d ",*(pcode+i));
  312.           printf("\n");
  313. */
  314.  
  315. return;
  316. fatal_err:
  317.     gprint("Aborting expression parsing. \n");
  318.     *plen = saveplen;
  319.     *rtype = 0;
  320. }
  321.  
  322. /*------------------------------------------------------------------*/
  323. /* append fcode to pcode */
  324. add_pcode(char *pcode,int *plen,char *fcode,int *flen)
  325. {
  326.     char *p;
  327.     p = pcode + *plen;
  328.     memcpy(p,fcode,*flen);
  329.     *plen = *plen + *flen;
  330. }
  331. add_i(char *pcode,int *plen,int32 i)
  332. {
  333.     int32 *p;
  334.     p = (int32 *) (pcode + *plen);
  335.     *p = i;
  336.     *plen += 4;
  337. }
  338. void long_set(char *pcode,int32 i)
  339. {
  340.     int32 *p;
  341.     p = (int32 *) (pcode);
  342.     *p = i;
  343. }
  344. add_f(char *pcode,int *plen,double f)
  345. {
  346.     union { double d ; int32 l[2]; short s[4]; } both;
  347.     both.d = f;
  348.     add_i(pcode,plen,2);
  349.     add_i(pcode,plen,both.l[0]);
  350.     add_i(pcode,plen,both.l[1]);
  351. }
  352. add_var(char *pcode,int *plen,int i)
  353. {
  354.     add_i(pcode,plen,3);
  355.     add_i(pcode,plen,i);
  356. }
  357. add_strvar(char *pcode,int *plen,int i)
  358. {
  359.     add_i(pcode,plen,4);
  360.     add_i(pcode,plen,i);
  361. }
  362. add_fn(char *pcode, int *plen, int i)
  363. {
  364.     add_i(pcode,plen,i);
  365.     dbg gprint(" add Function %d \n",i);
  366. }
  367. add_string(char *pcode, int *plen, char *s)
  368. {
  369.     char *p;
  370.     int sl;
  371.     dbg gprint("adding string {%s} \n",s);
  372.     add_i(pcode,plen,5);
  373.     sl = strlen(s)+1;
  374.     p = pcode + *plen;
  375.     sl = ((sl + 3) & 0xfffc);
  376.      strncpy(p,s,sl);
  377.     *plen = *plen + sl;
  378. }
  379. /*------------------------------------------------------------------*/
  380. /* Remove the quotes from a string and return a modified pointer */
  381. char *un_quote(char *cts)
  382. {
  383.     int i,j;
  384.     i = strlen(cts);
  385.     if (*cts=='"') {
  386.         *(cts+i-1) = 0;
  387.         cts = cts + 1;
  388.     }
  389.     return cts;
  390. }
  391. /*------------------------------------------------------------------*/
  392. stack_op(char *pcode, int *plen, int stk[]
  393.     , int stkp[], int *nstk,  int i, int p)
  394. {
  395.     dbg gprint("Stack oper %d priority %d \n",i,p);
  396.     while (p<=stkp[*nstk] &&(*nstk)>0) {
  397.         dbg gprint("ADDING oper stack = %d  oper=%d \n",*nstk,stk[(*nstk)]);
  398.         add_i(pcode,plen,stk[(*nstk)--]);
  399.     }
  400.     stk[++(*nstk)] = i;
  401.     stkp[*nstk] = p;
  402. }
  403. isnumber(char *s)
  404. {
  405.     while (*s!='\0') {
  406.         if (isdigit(*s) || *s=='.' || *s=='E' ) s++;
  407.         else  return false;
  408.     }
  409.     return true;
  410. }
  411. lastchar(char *s, char c)
  412. {
  413.     while (*s!='\0') {s++;}
  414.     return *(--s)==c;
  415. }
  416.  
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.  
  434.